package net.oschina.bilbodai.common.retrofitor.support.parse;

import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.ParserContext;

/**
 * @author daimao  Date: 15/12/9 Time: 下午10:37
 * @version $Id$
 */
public class ContextUtils {

    public static BeanDefinition createSingletonDefinition(Class<?> type) {
        RootBeanDefinition beanDefinition = new RootBeanDefinition(type);
        beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
        return beanDefinition;
    }

    public static BeanDefinition findDefinitionByName(String beanName, ParserContext context) {
        try {
            return context.getRegistry().getBeanDefinition(beanName);
        } catch (NoSuchBeanDefinitionException e) {
            return null;
        }
    }

    public static String generateBeanName(BeanDefinition beanDefinition, ParserContext context) {
        return context.getReaderContext().generateBeanName(beanDefinition);
    }

    public static String registerBeanDefinition(ParserContext parserContext, BeanDefinition beanDefinition) {
        String beanName = parserContext.getReaderContext().registerWithGeneratedName(beanDefinition);
        parserContext.registerComponent(new BeanComponentDefinition(beanDefinition, beanName));
        return beanName;
    }

    public static void registerWithGivenName(String beanName, BeanDefinition beanDefinition, ParserContext context) {
        context.getRegistry().registerBeanDefinition(beanName, beanDefinition);
        context.registerBeanComponent(new BeanComponentDefinition(beanDefinition, beanName));
    }

    public static RuntimeBeanReference registerAndGetRuntimeBeanReference(ParserContext parserContext, BeanDefinition def, String beanName) {
        String name = beanName;
        if (beanName == null || beanName.length() == 0) {
            name = generateBeanName(def, parserContext);
        }
        registerWithGivenName(name, def, parserContext);
        return new RuntimeBeanReference(name);
    }

    public static RuntimeBeanReference registerAndGetRuntimeBeanReference(ParserContext parserContext, BeanDefinition def) {
        String name = generateBeanName(def, parserContext);
        registerWithGivenName(name, def, parserContext);
        return new RuntimeBeanReference(name);
    }

}